package eu.codlab.androidemu.services;

import java.io.IOException;
import java.util.UUID;

import eu.codlab.src.game.R;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class BluetoothServerService extends Service{
	public final static UUID MY_UUID = UUID.fromString("d4e1ffad-616b-405a-84ed-09e18a29af2e");
	private static CommandListener _command_listener;
	private static byte tmp[]=new byte [4];
	private AcceptThread thread;
	private static BluetoothState _state = BluetoothState.NOBLUETOOTH;

	private static BluetoothServerService _this;

	private Notification notification;

	public final static String NAME = "eu.codlab.game.commands";

	@Override
	public void onCreate(){
		_this = this;
	}

	@Override
	public IBinder onBind(Intent arg0) {
		_this = this;
		return null;
	}

	public void onDestroy(){
		thread.cancel();
		super.onDestroy();
	}
	@Override
	public int onStartCommand(Intent intent, int flags, int startId){
		_this = this;
		//this.startForeground(42, getNotification());
		//if(thread != null)
		//	thread.cancel();
		if(thread == null || thread.isClosed()){
			thread = new AcceptThread();
			thread.start();
		}
		return Service.START_STICKY;
	}

	public static BluetoothServerService getInstance(){
		return _this;
	}

	public static BluetoothState getBluetoothState(){
		return _state;
	}


	private static void setState(BluetoothState state){
		_state = state;
		refreshState();
	}
	public static void refreshState(){
		if(_command_listener != null)
			_command_listener.onBluetoothState(_state);
	}

	public static int getResourceBluetoothState(){
		return BluetoothStateHelper.getResourceFromBluetoothState(_state);
	}

	public void setCommandListener(CommandListener command_listener){
		_command_listener = command_listener;
	}

	private Notification getNotification(){
		CharSequence text = getText(R.string.app_label);
		notification = new Notification(R.drawable.app_icon, text,
				System.currentTimeMillis());
		/*PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, E2coAppActivity.class), 0);*/
		setNotificationText(R.string.service_started);

		return notification;
	}


	private final void setNotificationText(int text_id){
		/*if(contentIntent == null){
			contentIntent = PendingIntent.getBroadcast(this, 0, new Intent(), PendingIntent.FLAG_NO_CREATE);
		}

		//notification.setLatestEventInfo(this, getText(text_id),
		//		getText(R.string.app_label), contentIntent);
		 *
		 */
	}

	private class AcceptThread extends Thread {
		private BluetoothServerSocket _server_socket;
		private BluetoothAdapter _bluetooth_adapter;
		private boolean closed;
		public AcceptThread() {
			_server_socket = null;
			_bluetooth_adapter = BluetoothAdapter.getDefaultAdapter();
			
			if(_bluetooth_adapter != null){
				closed = false;
				BluetoothServerSocket tmp = null;
				try {
					Log.d("Bluetooth","creating with "+NAME+" "+MY_UUID.toString());
					tmp = _bluetooth_adapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
					setState(BluetoothState.CONNECTING);
				} catch (IOException e) {
					e.printStackTrace(); 
					setState(BluetoothState.CLOSED);


				}
				_server_socket = tmp;
			}
		}

		public boolean isClosed(){
			return closed == true || _server_socket == null;
		}

		public boolean manageConnectedSocket(BluetoothSocket socket) throws IOException{
			setNotificationText(R.string.service_waiting_data);
			if(socket.getInputStream().read(tmp) == 4){
				int cmd = tmp[1] + tmp[0]*256;
				int key_state = tmp[2];
				_command_listener.onCommand(cmd, key_state);
				//Log.d("Receiving",tmp[0] +" "+tmp[1]+" "+tmp[2]+" "+tmp[3]);
				return true;
			}
			return false;
		}
		public void run() {
			BluetoothSocket socket = null;
			boolean state;
			while (!closed && _server_socket != null) {
				try {					
					setState(BluetoothState.CONNECTING);
					Log.d("waiting...","CONNECTING");
					socket = _server_socket.accept();
					Log.d("waiting...","accetp");
					setState(BluetoothState.CONNECTED);

					setNotificationText(R.string.service_client_connected);
					state = manageConnectedSocket(socket);
					while(state){
						try{
							state = manageConnectedSocket(socket);
						}catch(Exception e){
							socket = null;
							state = false;
							e.printStackTrace();
						}
					}
					setState(BluetoothState.CLOSED);
					socket.close();
				} catch (Exception e) {
					e.printStackTrace();
					setState(BluetoothState.CLOSED);
				}
			}
		}

		public void cancel() {
			try {
				if(_server_socket != null)
					_server_socket.close();
			} catch (IOException e) { 
				e.printStackTrace();
			}
			setState(BluetoothState.CLOSED);
			closed = true;
		}
	}

}
